home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / ge_cool.lha / GE_COOL2.1 / src / Rational / Rational.h < prev   
C/C++ Source or Header  |  1992-07-14  |  16KB  |  425 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12. //
  13. // Created: MBN 10/25/89 -- Initial design and implementation
  14. // Updated: MBN 03/04/90 -- Added execption for DIVIDE_BY_ZERO
  15. // Updated: MJF 07/31/90 -- Added terse print
  16. // Updated: DLS 04/01/91 -- New lite version
  17. //
  18. // The Rational class  implements rational numbers  and arithmetic.  A Rational
  19. // object has the same precision and range of values as the built-in type long.
  20. // Implicit conversion to the system defined types short, int, long, float, and
  21. // double is supported by  overloaded  operator member functions.  Although the
  22. // Rational class makes judicous use  of inline  functions and  deals only with
  23. // integral values, the user  is warned that  the Rational  integer  arithmetic
  24. // class is still considerably slower than the built-in  integer data types. If
  25. // the range  of values  anticipated will  fit into a  built-in  type, use that
  26. // instead.
  27. //
  28. // The  Rational class implements   common  arithmetic exception  handling  and
  29. // provides  the  application  with  support for  detecting  negative infinity,
  30. // positive  infinity,  overflow, and underflow  as a result of some arithmetic
  31. // expression.  If  one of  these conditions or  an  attempt to  convert from a
  32. // Rational with no value to a built-in type is detected, an Error exception is
  33. // raised. The application programmer can provide an  exception handler to take
  34. // care of this problem. If  no such handler is  available, an error message is
  35. // printed and the application terminates.
  36. //
  37. // The Rational class requires several constants be defined to insure precision
  38. // and accuracy   of conversion.  The   preprocessor  symbols MINSHORT, MININT,
  39. // MINLONG, MAXSHORT, MAXINT, and MAXLONG  are calculated  in the <misc.h>
  40. // header file  via various  bit  manipulation  macros. The  symbols  MINFLOAT,
  41. // MINDOUBLE,  MAXFLOAT,  and MAXDOUBLE  are  system dependent  and cannot   be
  42. // calculated.  Most systems typically have  values  for these constants in the
  43. // system header  file <values.h>.  Values  for a  specific  machine should  be
  44. // copied into the <misc.h> header file as necessary.
  45. //
  46. // The private data section of the Rational class contains two long data slots,
  47. // one for the numerator and one for the denominator.   The Rational class also
  48. // contains a private  data slot  providing arithmetic exception status.  There
  49. // are five constructors for the Rational class.  The first is  a simple inline
  50. // constructor that initializes the state and private  data slots.   The second
  51. // takes two integers (short, int, or long) and uses them as the  initial value
  52. // for  the  object.   The second  argument is  optional  and if  not supplied,
  53. // defaults to one.  The third  takes two longs  and  uses  them as the initial
  54. // value for the object.  The second argument is optional and  if not supplied,
  55. // defaults to one.  The  fourth takes a  double  and  calculates an equivalent
  56. // normalized rational.  Finally, the fifth takes  a const reference to another
  57. // Rational object and duplicates its state and value.
  58. //
  59. // The Rational class  provides overloaded operators for addition, subtraction,
  60. // multiplication,  division, and  modulus.  Also  available are inequality and
  61. // equality,  assignment, increment, decrement,  unary  minus, ones-complement,
  62. // output, less than, greater than,  less than or  equal, and greater  than  or
  63. // equal.  Methods to get the numerator  and denominator, invert, calculate the
  64. // floor  and ceiling, truncate,  and round are  supported. Finally,  five type
  65. // conversion functions to short, int, long, float, and double are provided.
  66.  
  67. #ifndef RATIONAL_H                // If no Rational definition
  68. #define RATIONAL_H                // define the Rational symbol
  69.  
  70. #ifndef STREAMH            // If the Stream support not yet defined,
  71. #if defined(DOS) || defined(M_XENIX)
  72. #include <stream.hxx>        // include the Stream class header file
  73. #else
  74. #include <stream.h>        // include the Stream class header file
  75. #endif
  76. #define STREAMH
  77. #endif
  78.  
  79. #ifndef MISCELANEOUSH            // If we have not included this file
  80. #include <misc.h>        // Include miscellaneous useful defs
  81. #endif
  82.  
  83.  
  84. class CoolRational {
  85. public:
  86.   inline CoolRational ();            // Simple constructor
  87.   CoolRational (long, long d = 1);        // Constructor with longs
  88.   CoolRational (const CoolRational&);        // Copy constructor
  89.   inline ~CoolRational();            // destructor
  90.   
  91.   inline long numerator () const;        // Get the numerator
  92.   inline long denominator () const;        // Get the denominator
  93.   inline N_status status () const;        // Return Number status
  94.   
  95.   inline CoolRational& operator= (const CoolRational&);    // Overload assignment
  96.   inline Boolean operator== (const CoolRational&) const; // Overload equality
  97.   inline Boolean operator!= (const CoolRational&) const; // Overload inequality
  98.   
  99.   inline CoolRational operator-() const;    // Unary minus operator
  100.   inline Boolean operator!() const;        // Unary not operator
  101.   
  102.   CoolRational& operator+= (const CoolRational&); // Overload plus/assign
  103.   CoolRational& operator-= (const CoolRational&); // Overload minus/assign
  104.   CoolRational& operator*= (const CoolRational&); // Overload multiply/assign
  105.   CoolRational& operator/= (const CoolRational&); // Overload divide/assign
  106.   CoolRational& operator%= (const CoolRational&); // Overload modulus/assign
  107.   
  108.   inline friend CoolRational operator+ (const CoolRational&, const CoolRational&);
  109.   inline friend CoolRational operator- (const CoolRational&, const CoolRational&);
  110.   inline friend CoolRational operator* (const CoolRational&, const CoolRational&);
  111.   inline friend CoolRational operator/ (const CoolRational&, const CoolRational&);
  112.   inline friend CoolRational operator% (const CoolRational&, const CoolRational&); 
  113.  
  114.   inline CoolRational& operator++ ();        // Overload increment
  115.   inline CoolRational& operator-- ();        // Overload decrement
  116.   
  117.   Boolean operator< (const CoolRational&) const; // Overload less than
  118.   inline Boolean operator<= (const CoolRational&) const; // Overload less/equal
  119.   Boolean operator> (const CoolRational&) const;     // Overload greater than
  120.   inline Boolean operator>= (const CoolRational&) const; // Overload greater/equal
  121.   
  122.   friend ostream& operator<< (ostream&, const CoolRational&); // Output ref
  123.   inline friend ostream& operator<< (ostream&, const CoolRational*); // Output ptr
  124.   
  125.   void print(ostream&);                // Terse print
  126.   
  127.   CoolRational& invert ();            // Invert the rational number
  128.   inline long floor () const;            // Truncate towards -infinity
  129.   inline long ceiling () const;            // Truncate towards +infinity
  130.   inline long truncate () const;        // Truncate towards zero
  131.   long round () const;                // Truncate to nearest integer
  132.   
  133.   operator short ();                // Implicit conversion
  134.   operator int ();                // Implicit conversion
  135.   operator long ();                // Implicit conversion
  136.   operator float ();                // Implicit conversion
  137.   inline operator double ();            // Implicit conversion
  138.  
  139. private:
  140.   long num;                    // Numerator portion
  141.   long den;                    // Denominator portion
  142.   N_status state;                // Exception status
  143.   
  144.   long gcd (long, long);            // Calculate GCD
  145.   void normalize ();                // Normalize num/den 
  146.   void minus_infinity (const char*) const;    // Raise - infinity exception
  147.   void plus_infinity (const char*) const;    // Raise + infinity exception
  148.   void overflow (const char*) const;        // Raise overflow error
  149.   void underflow (const char*) const;        // Raise underflow error
  150.   void divide_by_zero (const char*) const;    // Raise divide by zero error
  151. };
  152.  
  153.  
  154. // Rational -- Simple constructor
  155. // Input:      None
  156. // Output:     None
  157.  
  158. inline CoolRational::CoolRational () {
  159.   this->num = this->den = 0;            // Initialize data slots
  160.   this->state = N_OK;                // Set status to OK
  161. }
  162.  
  163.  
  164. // Rational -- Copy constructor
  165. // Input:      Reference to rational object
  166. // Output:     None
  167.  
  168. inline CoolRational::CoolRational (const CoolRational& r) {
  169.   this->num = r.num;                // Set numerator
  170.   this->den = r.den;                // Set denominator
  171.   this->state = r.state;            // Set state
  172. }
  173.  
  174. // ~Rational -- Destructor does nothing
  175.  
  176. inline CoolRational::~CoolRational() {}
  177.  
  178. // numerator -- Return the numerator portion of the rational
  179. // Input:       None
  180. // Output:      Numerator of rational
  181.  
  182. inline long CoolRational::numerator () const {
  183.   return this->num;                // Return numerator
  184. }
  185.  
  186.  
  187. // denominator -- Return the denominator portion of the rational
  188. // Input:         None
  189. // Output:        Denominator of rational
  190.  
  191. inline long CoolRational::denominator () const {
  192.   return this->den;                // Return denominator
  193. }
  194.  
  195.  
  196. // status -- Return the status of Number
  197. // Input:    None
  198. // Output:   N_status enum value
  199.  
  200. inline N_status CoolRational::status () const {
  201.   return this->state;
  202. }
  203.  
  204.  
  205. // operator= -- Overload the assignment operator for the Rational class
  206. // Input:       Reference to rational object
  207. // Output:      Reference to updated rational object
  208.  
  209. inline CoolRational& CoolRational::operator= (const CoolRational& r) {
  210.   this->num = r.num;                // Set numerator
  211.   this->den = r.den;                // Set denominator
  212.   this->state = r.state;            // Set state
  213.   return *this;                    // Return reference
  214. }
  215.   
  216.  
  217. // operator== -- Overload the equality operator for the rational class
  218. // Input:        Reference to rational object
  219. // Output:       TRUE/FALSE
  220.  
  221. inline Boolean CoolRational::operator== (const CoolRational& r) const {
  222.   return (this->num == r.num && this->den == r.den);
  223. }
  224.  
  225.  
  226. // operator!= -- Overload the inequality operator for the Rational class
  227. // Input:        Reference to a constant rational object
  228. // Ouput:        TRUE/FALSE
  229.  
  230. inline Boolean CoolRational::operator!= (const CoolRational& r) const {
  231.   return !(*this == r);
  232. }
  233.  
  234.  
  235. // operator< -- Overload operator less than for the rational class
  236. // Input:       Reference to rational number
  237. // Output:      TRUE/FALSE
  238.  
  239. inline Boolean CoolRational::operator< (const CoolRational& r) const {
  240.   if (this->den == r.den)            // If same denominator
  241.     return (this->num < r.num);            // Return less than sense
  242.   else                        // Else calculate common denom.
  243.     return ((this->num * r.den) < (this->den * r.num));    // And return state
  244. }
  245.  
  246.  
  247. // operator> -- Overload operator greater than for the rational class
  248. // Input:       Reference to rational number
  249. // Output:      TRUE/FALSE
  250.  
  251. inline Boolean CoolRational::operator> (const CoolRational& r) const {
  252.   if (this->den == r.den)            // If same denominator
  253.     return (this->num > r.num);            // Return greater than sense 
  254.   else                        // Else calculate common denom.
  255.     return ((this->num * r.den) > (this->den * r.num));    // And return state
  256. }
  257.  
  258.  
  259. // operator<= -- Overload the less than or equal to operator for rational
  260. // Input:        Reference to a constant rational object
  261. // Output:       TRUE/FALSE
  262.  
  263. inline Boolean CoolRational::operator<= (const CoolRational& r) const {
  264.   return !(*this > r);
  265. }
  266.  
  267.  
  268. // operator>= -- Overload the greater than or equal to operator for rational
  269. // Input:        Reference to a constant rational object
  270. // Output:       TRUE/FALSE
  271.  
  272. inline Boolean CoolRational::operator>= (const CoolRational& r) const {
  273.   return !(*this < r);
  274. }
  275.  
  276.  
  277. // operator<< -- Overload the output operator for a reference to a rational
  278. // Input:        Reference to an ostream
  279. // Output:       Reference to an ostream
  280.  
  281. inline ostream& operator<< (ostream& os, const CoolRational& r) {
  282.   os << r.num << "/" << r.den;            // Output rational number
  283.   return os;                    // Return ostream reference
  284. }
  285.  
  286.  
  287. // operator<< -- Overload the output operator for a pointer to a rational
  288. // Input:        Ostream reference, pointer to a rational object
  289. // Output:       Ostream reference
  290.  
  291. inline ostream& operator<< (ostream& os, const CoolRational* r) {
  292.   return operator<< (os, *r);
  293. }
  294.  
  295.  
  296. // operator- -- Overload the unary minus operator for the Rational class
  297. // Input:       None
  298. // Output:      Negated rational value
  299.  
  300. inline CoolRational CoolRational::operator- () const {
  301.   CoolRational r (-this->num, this->den);    // Get negative value
  302.   return r;                    // Return deferenced pointer
  303. }
  304.  
  305.  
  306. // operator! -- Overload the negation operator for the Rational class
  307. // Input:       None
  308. // Output:      TRUE/FALSE
  309.  
  310. inline Boolean CoolRational::operator! () const {
  311.   return ((this->num == 0) ? TRUE : FALSE);    // Return logical state
  312. }
  313.  
  314.  
  315. // operator++ -- Overload the increment operator for the Rational class
  316. // Input:        None
  317. // Output:       Reference to updated rational object
  318.  
  319. inline CoolRational& CoolRational::operator++ () {
  320.   this->num += this->den;            // Increment numerator
  321.   return *this;                    // Return updated object
  322. }
  323.   
  324.  
  325. // operator-- -- Overload the decrement operator for the Rational class
  326. // Input:        None
  327. // Output:       Reference to updated rational object
  328.  
  329. inline CoolRational& CoolRational::operator-- () {
  330.   this->num -= this->den;            // Decrement numerator
  331.   return *this;                    // Return updated object
  332. }
  333.  
  334.  
  335. // truncate -- Converts rational value by truncating towards zero
  336. // Input:      None
  337. // Output:     long truncated value
  338.  
  339. inline long CoolRational::truncate () const {
  340.   return (long) (this->num / this->den);    // Return truncated rational
  341. }
  342.  
  343.  
  344. // floor -- Converts rational value by truncating towards negative infinity
  345. // Input:   None
  346. // Output:  long value of truncated rational
  347.  
  348. inline long CoolRational::floor () const {
  349.   long temp = this->truncate ();        // Get truncated value
  350.   return ((this->num < 0.0 && (-(this->num%this->den) > 0.5*this->den)) ?
  351.       (temp - 1) : temp);
  352. }
  353.  
  354.  
  355. // ceiling -- Converts rational value by truncating towards positive infinity
  356. // Input:     None
  357. // Output:    long value of truncated rational
  358.  
  359. inline long CoolRational::ceiling () const {
  360.   long temp = this->truncate ();        // Get truncated value
  361.   return ((this->num > 0.0 && ((this->num%this->den) > 0.5*this->den)) ?
  362.       (temp + 1) : temp);
  363. }
  364.  
  365.  
  366. // operator+ -- Overload the addition operator for rational
  367. // Input:       Reference to two rational numbers
  368. // Output:      A new rational number
  369.  
  370. inline CoolRational operator+ (const CoolRational& r1, const CoolRational& r2) {
  371.   CoolRational result(r1);
  372.   result += r2;
  373.   return result;
  374. }
  375.  
  376. // operator- -- Overload the subtraction operator for rational
  377. // Input:       Reference to two rational numbers
  378. // Output:      A new rational number
  379.  
  380. inline CoolRational operator- (const CoolRational& r1, const CoolRational& r2) {
  381.   CoolRational result(r1);
  382.   result -= r2;
  383.   return result;
  384. }
  385.  
  386. // operator* -- Overload the multiplication operator for rational
  387. // Input:       Reference to two rational numbers
  388. // Output:      A new rational number
  389.  
  390. inline CoolRational operator* (const CoolRational& r1, const CoolRational& r2) {
  391.   CoolRational result(r1);
  392.   result *= r2;
  393.   return result;
  394. }
  395.  
  396. // operator/ -- Overload the division operator for rational
  397. // Input:       Reference to two rational numbers
  398. // Output:      A new rational number
  399.  
  400. inline CoolRational operator/ (const CoolRational& r1, const CoolRational& r2) {
  401.   CoolRational result(r1);
  402.   result /= r2;
  403.   return result;
  404. }
  405.  
  406. // operator% -- Overload the remainder operator for rational
  407. // Input:       Reference to two rational numbers
  408. // Output:      A new rational number
  409.  
  410. inline CoolRational operator% (const CoolRational& r1, const CoolRational& r2) {
  411.   CoolRational result(r1);
  412.   result %= r2;
  413.   return result;
  414. }
  415.  
  416. // operator double -- Implicit conversion operator from Rational to a double
  417. // Input:             None
  418. // Output:            Double value equivalent to rational
  419.  
  420. inline CoolRational::operator double () {
  421.   return ((double)this->num)/((double)this->den);     // Double answer
  422. }
  423.  
  424. #endif RATIONAL_H                    // End RATIONALH
  425.